
#include "hitlist_backup.hpp"
#include "backup.hpp"
#include "hit_json.hpp"

#include <iostream>
hitlist_backup::~hitlist_backup()
{
  //delete _binary;
  //delete _json;
}

hitlist_backup::hitlist_backup()
  : _binary(0)
  , _json(0)
  , _test_mode(0)
{
}

void hitlist_backup::test_mode(bool enable)
{
  _test_mode = enable;
}

void hitlist_backup::binary_backup(backup* b)
{
  _binary = b;
}

void hitlist_backup::json_backup(backup* b)
{
  _json = b;
}

void hitlist_backup::flush()
{
  if ( _binary ) _binary->flush();
  if ( _json ) _json->flush();
}


void hitlist_backup::write_hit(user_id_t first_id, user_id_t second_id, time_t hit_time)
{
  hit h(first_id, second_id, hit_time);
  time_t now = _test_mode ? h.hit_time : time(0);
  if ( now == 0 ) now = time(0);

  if (_binary)
    _binary->write(now, (const char*)(&h), sizeof(h) );
  
  if ( _json )
  {
    /// Это сериализатор
    char* end = (hit_json_backup::serializer()(h, _buff));
    /// В _buff сериализованный json объект 
    _json->write( now,  _buff, end - _buff  );
  }
}

void hitlist_backup::restore(bool binary, ihitlist* hl, int day_ago)
{
  // 00:00 текущего дня
  time_t now = time(0);
  std::vector<char> data;
  int hour_ago = day_ago*24;
  /// Для каждого часа начиная с самого древнего
  for ( int d = hour_ago; d >= 0 ; --d )
  {

    if ( d%24 == 0) std::cout << d/24;

    /// Читаем файл целиком
    if ( ( binary ? _binary : _json ) -> read( now, d, data)  )
    {
      std::cout << ".";
      std::cout.flush();
      if ( !data.empty() )
      {
        if ( binary )
        {
          const hit *beg = reinterpret_cast<const hit *>(&(data.front()));
          const hit *end = beg + data.size() / sizeof(hit);
          for ( ;beg!=end; ++beg )
            hl->hit(beg->first_id, beg->second_id, beg->hit_time);
        }
        else
        {
          hit h;
          const char *beg = &(data.front());
          const char *end = beg + data.size();
          while ( beg!=end )
          {
            /// Это десеарилизатор
            /// После beg указывает на символ за последним, то есть на начало следующего
            beg = (hit_json_backup::serializer()(h, beg, end));
            hl->hit(h.first_id, h.second_id, h.hit_time);
          }
        }
      }
    }
    else
    {

    }
  }
}
